package fr.sedoo.commons.client.widget.map.impl;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import fr.sedoo.commons.client.image.CommonBundle;
import fr.sedoo.commons.client.util.UuidUtil;
import fr.sedoo.commons.client.widget.editing.impl.DefaultEditor;
import fr.sedoo.commons.shared.domain.GeographicBoundingBoxDTO;

/**
 * Widget affichant une carte et des zones de texte Nord, Est, Sud, Ouest <br>
 * - la carte permet le dessin/effacement d'une unique zone rectangulaire et le
 * déplacement de la carte<br>
 * - Les zones sont synchronisées avec le rectangle<br>
 * - Un mode "display" transforme les zones de saisie en zones d'affichage
 * 
 * 
 * @author andre
 * 
 */
public class SingleAreaSelectorWidget extends DefaultEditor implements Editor<GeographicBoundingBoxDTO>, RectangularAreaListener, RequiresResize {

	private static MapWidgetUiBinder uiBinder = GWT.create(MapWidgetUiBinder.class);

	interface AreaSelectorDriver extends SimpleBeanEditorDriver<GeographicBoundingBoxDTO, SingleAreaSelectorWidget> {
	}

	private AreaSelectorDriver driver = GWT.create(AreaSelectorDriver.class);

	@UiField
	TextBox northBoundLatitudeEditor;

	@UiField
	TextBox southBoundLatitudeEditor;

	@UiField
	TextBox eastBoundLongitudeEditor;

	@UiField
	TextBox westBoundLongitudeEditor;

	@Editor.Ignore
	@UiField
	Label northBoundLatitudeDisplay;

	@Editor.Ignore
	@UiField
	Label southBoundLatitudeDisplay;

	@Editor.Ignore
	@UiField
	Label eastBoundLongitudeDisplay;

	@Editor.Ignore
	@UiField
	Label westBoundLongitudeDisplay;

	@UiField
	Element leftColumn;

	@UiField
	Element rightColumn;

	@UiField(provided = true)
	AreaSelectorWidget areaSelector;

	private String identifier;

	interface MapWidgetUiBinder extends UiBinder<Widget, SingleAreaSelectorWidget> {
	}

	public SingleAreaSelectorWidget() {
		this(AreaSelectorWidget.DEFAULT_MAP_LAYER);
	}

	public SingleAreaSelectorWidget(String mapLayer) {
		areaSelector = new AreaSelectorWidget(mapLayer);
		CommonBundle.INSTANCE.css().ensureInjected();
		initWidget(uiBinder.createAndBindUi(this));
		driver.initialize(this);
		init();
	}

	protected void init() {

		editWidgets.add(northBoundLatitudeEditor);
		editWidgets.add(southBoundLatitudeEditor);
		editWidgets.add(eastBoundLongitudeEditor);
		editWidgets.add(westBoundLongitudeEditor);

		displayWidgets.add(northBoundLatitudeDisplay);
		displayWidgets.add(southBoundLatitudeDisplay);
		displayWidgets.add(eastBoundLongitudeDisplay);
		displayWidgets.add(westBoundLongitudeDisplay);

		areaSelector.addListener(this);
		areaSelector.activateDrawRectangularAreaControl();
	}

	protected void resetTextFields() {
		northBoundLatitudeEditor.setText("");
		southBoundLatitudeEditor.setText("");
		eastBoundLongitudeEditor.setText("");
		westBoundLongitudeEditor.setText("");
	}

	public GeographicBoundingBoxDTO getGeographicBoundingBoxDTO() {
		GeographicBoundingBoxDTO result = new GeographicBoundingBoxDTO();
		result.setEastBoundLongitude(eastBoundLongitudeEditor.getText());
		result.setWestBoundLongitude(westBoundLongitudeEditor.getText());
		result.setSouthBoundLatitude(southBoundLatitudeEditor.getText());
		result.setNorthBoundLatitude(northBoundLatitudeEditor.getText());
		return result;
	}

	public void setGeographicBoundingBoxDTO(GeographicBoundingBoxDTO box) {
		reset();

		northBoundLatitudeEditor.setText(box.getNorthBoundLatitude());
		northBoundLatitudeDisplay.setText(box.getNorthBoundLatitude());
		southBoundLatitudeEditor.setText(box.getSouthBoundLatitude());
		southBoundLatitudeDisplay.setText(box.getSouthBoundLatitude());
		eastBoundLongitudeEditor.setText(box.getEastBoundLongitude());
		eastBoundLongitudeDisplay.setText(box.getEastBoundLongitude());
		westBoundLongitudeEditor.setText(box.getWestBoundLongitude());
		westBoundLongitudeDisplay.setText(box.getWestBoundLongitude());
		onBoxChanged(null);
		if (getGeographicBoundingBoxDTO().isValid()) {
			areaSelector.zoomTo(identifier);
		} else {
			areaSelector.reset();
		}

		// center(box, true);
	}

	public void reset() {

		// RAZ des zones de textes
		resetTextFields();

		// RAZ des zones d'affichage
		northBoundLatitudeDisplay.setText("");
		southBoundLatitudeDisplay.setText("");
		eastBoundLongitudeDisplay.setText("");
		westBoundLongitudeDisplay.setText("");

		areaSelector.reset();
	}

	@Override
	public void enableDisplayMode() {
		super.enableDisplayMode();
		areaSelector.enableDisplayMode();
	}

	@Override
	public void enableEditMode() {
		super.enableEditMode();
		areaSelector.enableEditMode();
	}

	@UiHandler(value = { "northBoundLatitudeEditor", "southBoundLatitudeEditor", "eastBoundLongitudeEditor", "westBoundLongitudeEditor" })
	void onBoxChanged(ChangeEvent event) {

		GeographicBoundingBoxDTO box = getGeographicBoundingBoxDTO();
		if (box.isValid()) {
			areaSelector.destroyAll();
			String uuid = UuidUtil.uuid();
			box.setIdentifier(uuid);
			identifier = uuid;
			areaSelector.add(box);
		} else {
			identifier = "";
			areaSelector.destroyAllBut(identifier);
		}
	}

	@Override
	public void onRectangleAdded(GeographicBoundingBoxDTO box) {
		northBoundLatitudeEditor.setText(box.getNorthBoundLatitude());
		southBoundLatitudeEditor.setText(box.getSouthBoundLatitude());
		eastBoundLongitudeEditor.setText(box.getEastBoundLongitude());
		westBoundLongitudeEditor.setText(box.getWestBoundLongitude());
		identifier = box.getIdentifier();
		areaSelector.destroyAllBut(identifier);
	}

	@Override
	public void onRectangleDeleted(String uuid) {
		if (identifier.compareToIgnoreCase(uuid) == 0) {
			resetTextFields();
		}
	}

	@Override
	public void onRectangleUpdated(GeographicBoundingBoxDTO box) {
		// We dont need to manage this event
	}

	@Override
	public void onResize() {
		if (areaSelector != null) {
			areaSelector.onResize();
		}

	}

}
